package com.zjb.demo.system.service;

import com.mybatisflex.core.paginate.Page;
import com.mybatisflex.core.query.QueryChain;
import com.mybatisflex.core.query.QueryWrapper;
import com.mybatisflex.core.row.Db;
import com.mybatisflex.solon.service.impl.ServiceImpl;
import com.zjb.demo.system.domain.SysRole;
import com.zjb.demo.system.domain.SysUserRole;
import com.zjb.demo.system.domain.query.SysRoleQuery;
import com.zjb.demo.system.mapper.SysRoleDeptMapper;
import com.zjb.demo.system.mapper.SysRoleMapper;
import com.zjb.demo.system.mapper.SysRoleMenuMapper;
import com.zjb.demo.system.mapper.SysUserRoleMapper;
import org.noear.solon.annotation.Component;
import org.noear.solon.annotation.Inject;

import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import static com.zjb.demo.system.domain.table.SysRoleTableDef.SYS_ROLE;
import static com.zjb.demo.system.domain.table.SysUserRoleTableDef.SYS_USER_ROLE;

/**
 * @author 庄佳彬
 * @since 2023/12/28 23:20
 */
@Component
public class SysRoleService extends ServiceImpl<SysRoleMapper, SysRole> {
    @Inject
    private SysUserRoleMapper userRoleMapper;
    @Inject
    private SysRoleDeptMapper roleDeptMapper;
    @Inject
    private SysRoleMenuMapper roleMenuMapper;


    /**
     * 根据用户ID选择角色权限
     *
     * @param id 用户ID
     * @return 角色权限的集合
     */
    public Set<String> selectRolePermissionByUserId(Long id) {
        // 使用mapper的selectRolePermissionByUserId方法获取角色权限集合
        var perms = mapper.selectRolePermissionByUserId(id);

        // 对角色权限集合进行并行处理
        return perms.parallelStream()
                // 过滤空值
                .filter(Objects::nonNull)
                // 获取角色Key
                .map(SysRole::getRoleKey)
                // 将角色Key按照逗号分割
                .flatMap(it -> Stream.of(it.trim().split(",")))
                // 收集为Set集合
                .collect(Collectors.toSet());
    }


    /**
     * 分页查询系统角色列表
     *
     * @param query 查询条件
     * @return 分页对象
     */
    public Page<SysRole> pageList(SysRoleQuery query) {
        var page = new Page<SysRole>(query.getPageNum(), query.getPageSize());
        return queryChain(query)
                .page(page);
    }

    /**
     * 根据给定的查询条件，列出满足条件的SysRole对象集合。
     *
     * @param query SysRoleQuery对象，包含查询条件
     * @return 满足条件的SysRole对象集合
     */
    public List<SysRole> list(SysRoleQuery query) {
        return queryChain(query).list();
    }


    private QueryChain<SysRole> queryChain(SysRoleQuery query) {
        return queryChain()
                .select(SYS_ROLE.DEFAULT_COLUMNS)
                .from(SYS_ROLE)
                .where(SYS_ROLE.ROLE_NAME.eq(query.getRoleName()))
                .and(SYS_ROLE.ROLE_KEY.eq(query.getRoleKey()))
                .orderBy(SYS_ROLE.ROLE_SORT.asc());

    }

    /**
     * 判断角色名称是否存在
     *
     * @param roleName 角色名称
     * @return 如果角色名称存在则返回true，否则返回false
     */
    public boolean existsRoleName(String roleName) {
        return queryChain()
                .select(SYS_ROLE.ROLE_ID)
                .from(SYS_ROLE)
                .where(SYS_ROLE.ROLE_NAME.eq(roleName))
                .exists();
    }


    /**
     * 判断角色键是否存在
     *
     * @param roleKey 角色键
     * @return 如果角色键存在则返回true，否则返回false
     */
    public boolean existsRoleKey(String roleKey) {
        return queryChain()
                .select(SYS_ROLE.ROLE_ID)
                .from(SYS_ROLE)
                .where(SYS_ROLE.ROLE_KEY.eq(roleKey))
                .exists();
    }

    public void checkRoleDateScope(Long roleId) {
        //TODO do nothing 暂无数据权限实现
    }

    /**
     * 根据指定id更新状态
     *
     * @param status 新的状态值
     * @param roleId 角色id
     * @return 如果成功更新状态则返回true，否则返回false
     */
    public Boolean updateStatusById(String status, Long roleId) {
        return updateChain()
                .set(SYS_ROLE.STATUS, status)
                .where(SYS_ROLE.ROLE_ID.eq(roleId))
                .update();
    }


    /**
     * 根据提供的角色ID数组删除对应的角色。
     *
     * @param roleIds 角色ID数组
     * @return 删除是否成功
     */
    public Boolean removeByIds(Long[] roleIds) {
        var list = List.of(roleIds);
        return Db.txWithResult(() -> {
            roleDeptMapper.removeByRoleIds(list);
            roleMenuMapper.removeByRoleIds(list);
            return removeByIds(list);
        });
    }

    /**
     * 根据角色ID列表查询用户角色数量
     *
     * @param roleIds 角色ID列表
     * @return 用户角色数量
     */
    public long countRoleByRoleIds(List<Long> roleIds) {
        return userRoleMapper.countUserRoleByRoleId(roleIds);
    }

    /**
     * 删除用户角色关联信息
     *
     * @param userRole 用户角色信息
     * @return 删除是否成功
     */
    public Boolean deleteAuthUser(SysUserRole userRole) {
        return userRoleMapper.delete(userRole) > 0;
    }

    /**
     * 删除角色的用户关联信息
     *
     * @param roleId  角色ID
     * @param userIds 用户ID数组
     * @return 删除成功返回true，否则返回false
     */
    public Boolean deleteAuthUsers(Long roleId, Long[] userIds) {
        // 创建查询条件
        var query = QueryWrapper.create()
                .where(SYS_USER_ROLE.ROLE_ID.eq(roleId))
                .and(SYS_USER_ROLE.USER_ID.in(List.of(userIds)));

        // 调用mapper的deleteByQuery方法删除用户角色关联信息，并判断是否删除成功
        return userRoleMapper.deleteByQuery(query) > 0;
    }

    public Boolean insertAuthUsers(Long roleId, Long[] userIds) {
        var list = Stream.of(userIds)
                .map(userId -> new SysUserRole(userId, roleId))
                .toList();
        return userRoleMapper.insertBatch(list) > 0;
    }
}
